#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>

#include <ESP8266WiFi.h>      // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h> //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h> //  ESP8266WebServer库

const char *host = "192.168.43.224"; // 网络服务器IP
const int httpPort = 9292;           // http端口9292

ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(/*SCREEN_WIDTH*/ 128, /*SCREEN_HEIGHT*/ 64, &Wire, OLED_RESET);

String comdata = "";
bool flag_receive = false;

int stack[2] = {-1, -1};
int cdb1 = -1;
int cdb2 = -1;
int port = -1;
//int id

void setup()
{
    ledInit();
    Serial.begin(9600);
    Serial.println("Hello ESP8266."); // "初始化输出信息 hello world"

    /*
      ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
      ESP8266WebServer esp8266_server(80);// 建立网络服务器对象，该对象用于响应HTTP请求。监听端口（80）
  */
    Wire.begin(/*SDA*/ 5, /*SCL*/ 4);
    //display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false))
    { // Address 0x3C for 128x64
        Serial.println(F("SSD1306 allocation failed"));
        for (;;)
            ; // Don't proceed, loop forever
    }

    display.clearDisplay();
    display.setTextColor(WHITE); //字体颜色
    display.setCursor(10, 25);
    display.setTextSize(2);
    display.print("TC System");
    display.display();

    wifiMulti.addAP("thh123", "123123123");
    while (wifiMulti.run() != WL_CONNECTED)
    { // 尝试进行wifi连接。
        // delay(1000);
        lsLed();
        //    Serial.print(i++); Serial.print(' ');
    }

    closeAllLed();

    delay(1000);
    showCdb();
}

void loop()
{

    for (int i = 0; i < 2; i++)
    {
        if (stack[i] != -1)
        {
            wifiClientRequest(stack[i]);
        }
    }

    // 接收串口发来的数据
    while (Serial.available() > 0)
    {
        /* code */
        comdata += char(Serial.read());
        delay(2);
        flag_receive = true;
        // Serial.println(comdata);
    }
    //    Serial.println("com");
    //    Serial.println(comdata);

    if (flag_receive)
    {
        comdata.replace("\n", "");
        //        Serial.println(comdata);
        flag_receive = false;
        StaticJsonDocument<256> doc;
        DeserializationError err = deserializeJson(doc, comdata);
        JsonObject obj = doc.as<JsonObject>();
        if (err)
        {
            /* error */
            Serial.println("error");
            ClearAndDisplay("error");
            return;
        }
        int getCode = -1;
        getCode = obj[String("code")];
        /*首次归还*/
        if (getCode == 0)
        {
            int getIdNum = obj[String("id")];
            addCdb(getIdNum);
            reloadCdb();
        }
        if (getCode == 2)
        {
            int getIdNum = obj[String("id")];
        }
        //delay(2000);
        comdata = "";
        //Serial.println("over");
    }
}

void ClearAndDisplay(String str)
{
    display.clearDisplay();
    display.setTextSize(1);      //选择字号
    display.setTextColor(WHITE); //字体颜色
    display.print(comdata);
    display.display();
}

void addCdb(int id)
{
    //Serial.println("start add Cdb");
    if (stack[0] == -1)
    {
        stack[0] = id;
    }
    else
    {
        stack[1] = id;
    }

    if (id == 1001)
    {
        cdb1 = 1;
    }
    if (id == 1002)
    {
        cdb2 = 1;
    }

    // 向服务器发送归还请求
    returnCdb(id);

    //    for (int i = 0; i < 2; i++)
    //    {
    //        Serial.println(stack[i]);
    //    }
}

void deleteCdb(int id)
{
    if (stack[0] == id)
    {
        stack[0] = stack[1];
    }
    stack[1] = -1;
    if (id == 1001)
    {
        cdb1 = -1;
    }
    if (id == 1002)
    {
        cdb2 = -1;
    }
}

void reloadCdb()
{
    display.clearDisplay();
    display.setTextSize(1);      //选择字号
    display.setTextColor(WHITE); //字体颜色
    display.setCursor(0, 0);
    display.print("      TC System");
    //  display.print("123456789012345678901");
    display.setCursor(0, 15);
    display.print(" COM     Id   status");
    display.setCursor(0, 30);
    //    Serial.println(getCdbStr(stack[0], 1));
    display.print(getCdbStr(stack[0], 1));
    display.setCursor(0, 45);
    display.print(getCdbStr(stack[1], 2));
    display.display();
    reloadLed();
}

void showCdb()
{
    display.clearDisplay();
    display.setTextSize(1);      //选择字号
    display.setTextColor(WHITE); //字体颜色
    display.setCursor(0, 0);
    display.print("      TC System");
    //  display.print("123456789012345678901");
    display.setCursor(0, 15);
    display.print(" COM     Id   status");
    display.setCursor(0, 30);
    display.print("  1      --    --");
    display.setCursor(0, 45);
    display.print("  2      --    --");
    display.display();
}

String getCdbStr(int id, int index)
{
    //    Serial.println(index);
    String str = "  ";
    str.concat(index);
    int getId = id;
    //      "  1     1001    ok"
    if (getId != -1)
    {
        str += "     ";
        str += id;
        str += "    ok";
    }
    else
    {
        str += "      --";
        str += "     --";
    }

    return str;
}

void wifiClientRequest(int cdbId)
{
    WiFiClient client; // 建立WiFiClient对象

    //  Serial.print("Connecting to "); Serial.print(host);

    // 连接服务器
    if (client.connect(host, httpPort))
    {
        //        Serial.println(" Success!");

        //        Serial.println("id:" + cdbId);
        String jsonStr = String("") +
                         "{\"id\":" + cdbId + "}";
        // 建立客户端请求信息
        String httpRequest = String("GET /checkCdb?id=") + cdbId + " HTTP/1.1\r\n" +
                             "Host: " + host + "\r\n" +
                             "Connection: close\r\n" +
                             "\r\n";

        // 发送客户端请求
        //        Serial.println("Sending request: ");
        //        Serial.print(httpRequest);
        client.print(httpRequest);
        //                client.print(String("") + "Content-Length:" + jsonStr.length() + "\r\n\r\n");
        //            client.print(jsonStr);
        String line = "$";
        while (client.connected() || client.available())
        {
            String str = client.readStringUntil('\r');
            str.replace("\n", "");
            str.replace("\t", "");
            if (str.length() > 0)
            {
                line = str;
                line.replace("\n", "");
                //                Serial.println("**" + line);
            }
        }
        int status = line.toInt();
        //        Serial.println(String("result:") + line);
        if (status != 1)
        {
            deleteCdb(cdbId);
            reloadCdb();
            ledBlue(cdbId);
        }
    }
    else
    {
        Serial.println(" failed!");
    }

    //    Serial.println("===============");
    client.stop(); // 停止客户端
}

void returnCdb(int cdbId)
{
    WiFiClient client; // 建立WiFiClient对象

    // 连接服务器
    if (client.connect(host, httpPort))
    {
        //        Serial.println(" Success!");

        //        Serial.println("id:" + cdbId);
        String jsonStr = String("") +
                         "{\"id\":" + cdbId + "}";
        // 建立客户端请求信息
        String httpRequest = String("GET /returnCdb?id=") + cdbId + " HTTP/1.1\r\n" +
                             "Host: " + host + "\r\n" +
                             "Connection: close\r\n" +
                             "\r\n";

        client.print(httpRequest);
        String line = "$";
        while (client.connected() || client.available())
        {
            String str = client.readStringUntil('\r');
            str.replace("\n", "");
            str.replace("\t", "");
            if (str.length() > 0)
            {
                line = str;
                line.replace("\n", "");
                //                Serial.println("**" + line);
            }
        }
        int status = line.toInt();
        //        Serial.println(String("result:") + line);
    }
    else
    {
        Serial.println(" failed!");
    }

    // Serial.println("===============");
    client.stop(); // 停止客户端
}

void ledInit()
{
    pinMode(0, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(14, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(16, OUTPUT);
    pinMode(13, OUTPUT);
}

void lsLed()
{
    ledr(0);
    ledr(2);
    ledr(14);
    ledr(12);
    ledr(16);
    ledr(13);
}

void closeAllLed()
{
    digitalWrite(0, LOW);
    digitalWrite(2, LOW);
    digitalWrite(14, LOW);
    digitalWrite(12, LOW);
    digitalWrite(16, LOW);
    digitalWrite(13, LOW);
}

void ledr(int led)
{
    digitalWrite(led, LOW);
    delay(500);
    digitalWrite(led, HIGH);
    delay(500);
}

void reloadLed()
{
    if (cdb1 != -1)
    {
    digitalWrite(2,LOW);
        digitalWrite(0, HIGH);
    }
    else
    {
        digitalWrite(0, LOW);
    }
    if (cdb2 != -1)
    {
      digitalWrite(12,LOW);
        digitalWrite(14, HIGH);
    }
    else
    {
        digitalWrite(14, LOW);
    }
}

void ledBlue(int id)
{
    if (id == 1001)
    {
        for (int i = 0; i < 10; i++)
        {
            digitalWrite(16, HIGH);
            delay(300);
            digitalWrite(16, LOW);
            delay(300);
        }
        digitalWrite(2,HIGH);
    }
    if (id == 1002)
    {
        for (int i = 0; i < 10; i++)
        {
            digitalWrite(13, HIGH);
            delay(300);
            digitalWrite(13, LOW);
            delay(300);
        }
        digitalWrite(12,HIGH);
    }
    
}
